package com.lc.projects.sample.plan;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class TestDeepClone {
	public static void main(String[] args) {

		System.out.println("----------person------------");

		DeepTest t = new DeepTest("testa");
		DeepPerson p1 = new DeepPerson("a", 1);
		p1.setDeepTest(t);
		System.out.println(p1);
		System.out.println("------after----");
		DeepPerson p2 = (DeepPerson) p1.clone();
		p2.setAge(3);
		p2.getDeepTest().changeName();
		System.out.println(p1);
		System.out.println(p2);

	}
}

// clone后类变量指向的是同一个地址，如果要不影响 需要深度clone
class DeepPerson implements Cloneable, Serializable {
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	private DeepTest deepTest;

	public DeepTest getDeepTest() {
		return deepTest;
	}

	public void setDeepTest(DeepTest deepTest) {
		this.deepTest = deepTest;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public DeepPerson(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public DeepPerson() {
		super();
	}

	@Override
	public String toString() {
		return "DeepPerson [name=" + name + ", age=" + age + ", deepTest=" + deepTest + "]";
	}

	@Override
	protected Object clone() {
		Object cloneObj = null;
		try {
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ObjectOutputStream oo = new ObjectOutputStream(out);
			oo.writeObject(this);

			ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
			ObjectInputStream oi = new ObjectInputStream(in);
			cloneObj = oi.readObject();

		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return cloneObj;
	}

}

class DeepTest implements Serializable {
	
	private static DeepTest _instance = null;
	
	private Object readResolve(){
		System.out.println("_read resolve "+_instance);
		return _instance;
	}
	
	public static void changeInstance(){
		_instance = new DeepTest("abc");
	}
	
	public static DeepTest getInstance(){
		if(_instance == null)
			_instance = new DeepTest("test");
		
		System.out.println("getInstance "+_instance);
		return _instance;
	}
	
	private static final long serialVersionUID = 7491080380548681085L;
	
	private String name;

	public void changeName() {
		this.name = name + " change";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public DeepTest(String name) {
		super();
		this.name = name;
	}
	

	public static void main(String[] args) throws Exception {
		DeepTest d = DeepTest.getInstance();
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		ObjectOutputStream oo = new ObjectOutputStream(out);
		oo.writeObject(d);
		
		FileOutputStream o = new FileOutputStream("d:\\test.txt");
		o.write(out.toByteArray());
		o.flush();
		o.close();
		
		
		FileInputStream in = new FileInputStream("d:\\test.txt");
		ObjectInputStream oin = new ObjectInputStream(in);
		Object obj1 = oin.readObject();
		System.out.println(obj1);
		in.close();
		
		DeepTest.changeInstance();
		
		FileInputStream in2 = new FileInputStream("d:\\test.txt");
		ObjectInputStream oin2= new ObjectInputStream(in2);
		Object obj2 = oin2.readObject();
		System.out.println(obj2);
		in2.close();
		
		
		
	}
}